Published on

go的泛型参数如何比较大小?

Authors

可比较泛型

准确的说应该叫:可排序泛型

定义一个泛型函数:

func compare[T any](a, b T){
      if a > b{
          ...
      }
  }

通常用泛型的类型用any来表示,在比较any类型时会报错,不是所有类型都能做比较。go还提供另一个关键字comparable,泛型类型设为comparable还是不能比较大小,它只能用于比较 ==或者!=是布尔型。

在go的测试版中有内置的constraints包,将泛型设为constraints.Ordered类型即可限制泛型的类型一定为可比较大小的类型。

在测试版中移除内置的constraints包,在golang.org/x/exp/constraints导入,这个属于官方实验性质的包,并不推荐使用。

  type Ordered interface {
      // 有符号整型,无符号整型,浮点型,和字符串可以 比较大小
      Integer | Float | ~string
  }

  type Integer interface {
      Signed | Unsigned
  }

  type Signed interface {
      ~int | ~int8 | ~int16 | ~int32 | ~int64
  }

  type Unsigned interface {
      ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
  }

  type Float interface {
      ~float32 | ~float64
  }

在泛型中~Type后面跟类型,~ 符号用来指定类型的基础类型 (underlying type)。当使用在接口的类型约束中,~ 表示接受的是精确这个类型或者具有相同底层类型的任何类型。

这里约束可比较的类型有:示整型,浮点型和字符串型。

Go中可比较和可排序的类型

TypeComparableOrderedDescription
Boolean
Integer
Float
Complex分别比较实数和虚数,同时相等则两个复数相等。 如果需要比较大小,需要开发者分别比较实数和虚数。
String基于字节逐个比较。
Pointer如果两个指针指向同一个对象或者都为 nil,则两者相等。
Channel类似 Pointer,两个 Channel 变量只有都为 nil,或者指向同一个 Channel 的时候才相等。
Interface两个 interface 的 Type 和 Value 值同时相等时,两者才相等。
Struct⚠️仅当 Struct 内所有成员都是 Comparable,这个 Struct 才是 Comparable 的。 如果两个 struct 类型相同,且所有非空成员变量都相等,则两者相等。
Array⚠️仅当成员为 Comparable,Array 才是 Comparable 的。 如果两个 Array 中的每一个元素一一相等时,则两个 Array 相等。
Map
Slice
Func